package com.sc.gateway.util;

import com.alibaba.fastjson.JSON;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 令牌
 *
 * @author 徐赫阳
 * @date 2021/09/03
 */
public class Token {
    /* 秘钥 */
    private static final byte[] SECRET = "ZUOFEI_MYCODINGLIFE_15904092921@163.COM".getBytes();


    /**
     * 创建令牌
     *
     * @param payload 有效载荷
     * @return {@link String}
     * @throws Exception 异常
     */
    public static String createToken(Map payload) throws Exception{
        String tokenString = null;
        /**
         * 1.创建一个32-byte的密匙
         */
        MACSigner macSigner = new MACSigner(SECRET);
        /**
         * 2. 建立payload 载体
         */
        JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
                .subject("doi")
                .issuer("http://www.doiduoyi.com")
                .expirationTime(new Date(System.currentTimeMillis() + 1000 * 60 * 30))
                .claim("ACCOUNT", JSON.toJSONString(payload))
                .build();
        /**
         * 3. 建立签名
         */
        SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256), claimsSet);
        signedJWT.sign(macSigner);
        /**
         * 4. 生成token
         */
        String token = signedJWT.serialize();
        return token;
    }

    /**
     * 校验token是否合法，返回用户jsonString
     * <p>
     *
     * @param token 令牌
     * @return String
     * @throws Exception 异常
     */

    public static String validToken(String token) throws Exception{
        Map resultMap = new HashMap();
        SignedJWT jwt = SignedJWT.parse(token);
        JWSVerifier verifier = new MACVerifier(SECRET);
        //校验是否有效
        if (!jwt.verify(verifier)) {
            throw new Exception("Token 无效");
        }
        //校验超时
        Date expirationTime = jwt.getJWTClaimsSet().getExpirationTime();
        if (new Date().after(expirationTime)) {
            throw new Exception("Token 已过期");
        }
        //获取载体中的数据
        Object account = jwt.getJWTClaimsSet().getClaim("ACCOUNT");
        //是否有openUid
        if (Objects.isNull(account)){
            throw new Exception("Token 无效");
        }
        return account.toString();
    }


}
